<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>KML/KMZ 合并工具</title>
    <!-- 本地引用Tailwind CSS -->
    <script src="assets/js/tailwind.min.js"></script>
    <!-- 引入JSZip库处理KMZ文件 -->
    <script src="assets/js/jszip.min.js"></script>
    <!-- 本地引用font-awesome.min.css-->
    <link href="assets/css/font-awesome.min.css" rel="stylesheet">
    <script>
        tailwind.config = {
            theme: {
                extend: {
                    colors: {
                        primary: '#165DFF',
                        secondary: '#0FC6C2',
                        neutral: '#F2F3F5',
                        dark: '#1D2129',
                        error: '#F53F3F',
                    },
                    fontFamily: {
                        inter: ['Inter', 'system-ui', 'sans-serif'],
                    },
                }
            }
        }
    </script>
    <style type="text/tailwindcss">
        @layer utilities {
            .content-auto {
                content-visibility: auto;
            }
            .transition-all-300 {
                transition: all 300ms ease-in-out;
            }
            .shadow-hover {
                transition: all 0.3s ease;
            }
            .shadow-hover:hover {
                transform: translateY(-2px);
                box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
            }
            .error-shake {
                animation: shake 0.5s cubic-bezier(.36,.07,.19,.97) both;
            }
            @keyframes shake {
                10%, 90% { transform: translateX(-1px); }
                20%, 80% { transform: translateX(2px); }
                30%, 50%, 70% { transform: translateX(-4px); }
                40%, 60% { transform: translateX(4px); }
            }
        }
    </style>
</head>
<body class="font-inter bg-gray-50 text-dark min-h-screen flex flex-col">
    <!-- 顶部导航栏 -->
    <header class="bg-white shadow-sm sticky top-0 z-50">
        <div class="container mx-auto px-4 py-4 flex justify-between items-center">
            <div class="flex items-center space-x-2">
                <i class="fa fa-map-marker text-primary text-2xl"></i>
                <h1 class="text-xl md:text-2xl font-bold text-dark">KML/KMZ 合并工具</h1>
            </div>
            <div class="hidden md:flex items-center space-x-4">
                <button id="theme-toggle" class="p-2 rounded-full hover:bg-gray-100 transition-all-300">
                    <i class="fa fa-moon-o text-gray-600"></i>
                </button>
                <button class="p-2 rounded-full hover:bg-gray-100 transition-all-300">
                    <i class="fa fa-question-circle text-gray-600"></i>
                </button>
            </div>
        </div>
    </header>

    <!-- 主内容区 -->
    <main class="flex-grow container mx-auto px-4 py-8">
        <!-- 欢迎部分 -->
        <section class="text-center mb-12">
            <h2 class="text-[clamp(1.5rem,3vw,2.5rem)] font-bold text-dark mb-4">合并多个 KML/KMZ 文件</h2>
            <p class="text-gray-600 max-w-2xl mx-auto">
                简单、快速地将多个 KML 或 KMZ 文件合并为一个文件，保留所有地理标记和样式。
                无需安装，完全在浏览器中运行，保护您的数据隐私。
            </p>
        </section>

        <!-- 文件上传区域 -->
        <section class="max-w-3xl mx-auto mb-12">
            <div id="drop-area" class="border-2 border-dashed border-gray-300 rounded-xl p-8 text-center bg-white shadow-sm hover:shadow-md transition-all-300">
                <i class="fa fa-cloud-upload text-4xl text-primary mb-4"></i>
                <h3 class="text-xl font-semibold mb-2">拖放文件到此处</h3>
                <p class="text-gray-500 mb-6">或者</p>
                <label for="file-input" class="bg-primary hover:bg-primary/90 text-white font-medium py-3 px-6 rounded-lg shadow-md shadow-primary/20 transition-all-300 cursor-pointer inline-flex items-center">
                    <i class="fa fa-folder-open mr-2"></i> 选择文件
                    <input id="file-input" type="file" multiple accept=".kml,.kmz" class="hidden">
                </label>
                <p class="text-gray-400 text-sm mt-4">支持的格式: .kml, .kmz</p>
            </div>
            
            <!-- 新增：错误提示区域 -->
            <div id="upload-error" class="mt-4 hidden">
                <div class="bg-red-50 border-l-4 border-red-400 text-red-700 p-4 rounded-r-lg">
                    <div class="flex">
                        <div class="flex-shrink-0">
                            <i class="fa fa-exclamation-circle text-red-500"></i>
                        </div>
                        <div class="ml-3">
                            <h3 class="text-sm font-medium" id="error-title">上传错误</h3>
                            <div class="mt-2 text-sm" id="error-message">
                                <p></p>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </section>

        <!-- 合并选项 -->
        <section id="merge-options" class="max-w-3xl mx-auto mb-12 bg-white rounded-xl shadow-sm p-6 hidden">
            <h3 class="text-lg font-semibold mb-4 flex items-center">
                <i class="fa fa-sliders mr-2 text-primary"></i> 合并选项
            </h3>
            
            <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
                <!-- 输出格式 -->
                <div>
                    <label class="block text-gray-700 font-medium mb-2">输出格式</label>
                    <div class="flex space-x-4">
                        <label class="inline-flex items-center cursor-pointer">
                            <input type="radio" name="output-format" value="kml" class="form-radio h-5 w-5 text-primary" checked>
                            <span class="ml-2">KML</span>
                        </label>
                        <label class="inline-flex items-center cursor-pointer">
                            <input type="radio" name="output-format" value="kmz" class="form-radio h-5 w-5 text-primary">
                            <span class="ml-2">KMZ</span>
                        </label>
                    </div>
                </div>
                
                <!-- 文件命名 -->
                <div>
                    <label for="output-filename" class="block text-gray-700 font-medium mb-2">输出文件名</label>
                    <input type="text" id="output-filename" value="merged" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary/50 focus:border-primary transition-all-300">
                </div>
            </div>
            
            <!-- 高级选项 -->
            <div class="mt-6 pt-6 border-t border-gray-200">
                <div class="flex items-center justify-between mb-4">
                    <h4 class="font-medium text-gray-700">高级选项</h4>
                    <button id="toggle-advanced" class="text-primary text-sm hover:underline">
                        <i class="fa fa-chevron-down mr-1"></i> 显示
                    </button>
                </div>
                
                <div id="advanced-options" class="hidden">
                    <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
                        <!-- 保留原始样式 -->
                        <div>
                            <label class="flex items-center cursor-pointer">
                                <input type="checkbox" id="keep-styles" class="form-checkbox h-5 w-5 text-primary rounded" checked>
                                <span class="ml-2 text-gray-700">保留原始样式</span>
                            </label>
                        </div>
                        
                        <!-- 创建文件夹结构 -->
                        <div>
                            <label class="flex items-center cursor-pointer">
                                <input type="checkbox" id="create-folders" class="form-checkbox h-5 w-5 text-primary rounded" checked>
                                <span class="ml-2 text-gray-700">按源文件创建文件夹</span>
                            </label>
                        </div>
                    </div>
                </div>
            </div>
            
            <!-- 开始合并按钮 -->
            <div class="mt-8 text-center">
                <button id="merge-files" class="bg-primary hover:bg-primary/90 text-white font-medium py-3 px-8 rounded-lg shadow-md shadow-primary/20 transition-all-300 inline-flex items-center">
                    <i class="fa fa-compress mr-2"></i> 开始合并
                </button>
            </div>
        </section>

        <!-- 处理进度 -->
        <section id="processing-section" class="max-w-3xl mx-auto mb-12 hidden">
            <div class="bg-white rounded-xl shadow-sm p-6">
                <h3 class="text-lg font-semibold mb-4 flex items-center">
                    <i class="fa fa-cog fa-spin mr-2 text-primary"></i> 正在处理
                </h3>
                
                <div class="w-full bg-gray-200 rounded-full h-2.5 mb-4">
                    <div id="progress-bar" class="bg-primary h-2.5 rounded-full" style="width: 0%"></div>
                </div>
                
                <p id="progress-text" class="text-gray-600">准备中...</p>
            </div>
        </section>

        <!-- 结果区域 -->
        <section id="result-section" class="max-w-3xl mx-auto mb-12 hidden">
            <div class="bg-white rounded-xl shadow-sm p-6">
                <div class="flex items-center mb-4">
                    <div class="bg-green-100 rounded-full p-3 mr-4">
                        <i class="fa fa-check text-green-500 text-xl"></i>
                    </div>
                    <div>
                        <h3 class="text-lg font-semibold">处理完成</h3>
                        <p class="text-gray-600" id="result-filename"></p>
                    </div>
                </div>
                
                <!-- 只保留下载文件按钮 -->
                <div class="flex flex-wrap gap-4">
                    <a id="download-link" href="#" class="bg-primary hover:bg-primary/90 text-white font-medium py-3 px-6 rounded-lg shadow-md shadow-primary/20 transition-all-300 inline-flex items-center">
                        <i class="fa fa-download mr-2"></i> 下载文件
                    </a>
                </div>
            </div>
        </section>

        <!-- 已选文件列表（移至页面底部） -->
        <section id="file-list-section" class="max-w-3xl mx-auto mb-12 hidden">
            <div class="bg-white rounded-xl shadow-sm p-6">
                <div class="flex flex-wrap justify-between items-center mb-4">
                    <h3 class="text-lg font-semibold flex items-center">
                        <i class="fa fa-files-o mr-2 text-primary"></i> 已选择的文件
                        <span id="file-count" class="ml-2 text-sm bg-primary/10 text-primary px-2 py-0.5 rounded-full">0</span>
                    </h3>
                    <button id="clear-files" class="text-sm text-primary hover:text-primary/80 mt-2 sm:mt-0 transition-colors flex items-center">
                        <i class="fa fa-trash-o mr-1"></i> 清空所有文件
                    </button>
                </div>
                
                <div id="selected-files" class="grid grid-cols-1 gap-3 mt-4"></div>
            </div>
        </section>
    </main>

    <!-- 页脚 -->
    <footer class="bg-white border-t border-gray-200 py-6">
        <div class="container mx-auto px-4 text-center text-gray-500 text-sm">
            <p>© 2025 KML/KMZ 合并工具 | 所有操作均在您的浏览器中完成，不会上传数据到服务器</p>
        </div>
    </footer>

    <!-- JavaScript -->
    <script>
        // 全局变量
        let selectedFiles = [];
        let processedFiles = [];
        
        // DOM 元素
        const dropArea = document.getElementById('drop-area');
        const fileInput = document.getElementById('file-input');
        const fileListSection = document.getElementById('file-list-section');
        const selectedFilesContainer = document.getElementById('selected-files');
        const fileCount = document.getElementById('file-count');
        const mergeOptions = document.getElementById('merge-options');
        const processingSection = document.getElementById('processing-section');
        const progressBar = document.getElementById('progress-bar');
        const progressText = document.getElementById('progress-text');
        const resultSection = document.getElementById('result-section');
        const resultFilename = document.getElementById('result-filename');
        const downloadLink = document.getElementById('download-link');
        const processAnother = document.getElementById('process-another');
        const outputFilename = document.getElementById('output-filename');
        const toggleAdvanced = document.getElementById('toggle-advanced');
        const advancedOptions = document.getElementById('advanced-options');
        const mergeFilesBtn = document.getElementById('merge-files');
        const uploadError = document.getElementById('upload-error');
        const errorTitle = document.getElementById('error-title');
        const errorMessage = document.getElementById('error-message');
        const clearFilesBtn = document.getElementById('clear-files');
        
        // 拖放事件处理
        ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
            dropArea.addEventListener(eventName, preventDefaults, false);
        });
        
        function preventDefaults(e) {
            e.preventDefault();
            e.stopPropagation();
        }
        
        ['dragenter', 'dragover'].forEach(eventName => {
            dropArea.addEventListener(eventName, highlight, false);
        });
        
        ['dragleave', 'drop'].forEach(eventName => {
            dropArea.addEventListener(eventName, unhighlight, false);
        });
        
        function highlight() {
            dropArea.classList.add('border-primary', 'bg-primary/5');
        }
        
        function unhighlight() {
            dropArea.classList.remove('border-primary', 'bg-primary/5');
        }
        
        // 处理文件拖放
        dropArea.addEventListener('drop', handleDrop, false);
        
        function handleDrop(e) {
            // 隐藏之前的错误提示
            hideError();
            
            const dt = e.dataTransfer;
            const files = dt.files;
            handleFiles(files);
        }
        
        // 处理文件选择
        fileInput.addEventListener('change', function() {
            // 隐藏之前的错误提示
            hideError();
            
            handleFiles(this.files);
        });
        
        // 处理选择的文件
        function handleFiles(files) {
            if (files.length === 0) return;
            
            // 过滤并验证文件
            const validFiles = [];
            const invalidFiles = [];
            
            Array.from(files).forEach(file => {
                const ext = file.name.split('.').pop().toLowerCase();
                if (ext === 'kml' || ext === 'kmz') {
                    validFiles.push(file);
                } else {
                    invalidFiles.push(file);
                }
            });
            
            // 显示错误提示（如果有无效文件）
            if (invalidFiles.length > 0) {
                showError(
                    '包含无效文件',
                    `以下文件格式不支持: ${invalidFiles.map(file => file.name).join(', ')}<br>请上传 .kml 或 .kmz 格式的文件。`
                );
                dropArea.classList.add('error-shake');
                setTimeout(() => dropArea.classList.remove('error-shake'), 500);
            }
            
            if (validFiles.length === 0) {
                return;
            }
            
            // 添加到已选文件列表
            selectedFiles = [...selectedFiles, ...validFiles];
            updateFileList();
            
            // 显示文件列表和合并选项
            fileListSection.classList.remove('hidden');
            mergeOptions.classList.remove('hidden');
            
            // 滚动到合并选项
            setTimeout(() => {
                mergeOptions.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
            }, 300);
        }
        
        // 更新文件列表
        function updateFileList() {
            selectedFilesContainer.innerHTML = '';
            fileCount.textContent = selectedFiles.length;
            
            selectedFiles.forEach((file, index) => {
                const fileItem = document.createElement('div');
                fileItem.className = 'bg-white border border-gray-200 rounded-lg p-3 flex items-center justify-between shadow-hover';
                
                const fileInfo = document.createElement('div');
                fileInfo.className = 'flex items-center';
                
                const fileIcon = document.createElement('div');
                fileIcon.className = 'bg-primary/10 text-primary rounded-md p-2 mr-3';
                const ext = file.name.split('.').pop().toLowerCase();
                fileIcon.innerHTML = `<i class="fa fa-file-${ext === 'kml' ? 'code' : 'archive'}-o text-lg"></i>`;
                
                const fileName = document.createElement('div');
                fileName.className = 'overflow-hidden';
                const fileNameText = document.createElement('p');
                fileNameText.className = 'font-medium truncate max-w-xs md:max-w-md';
                fileNameText.textContent = file.name;
                const fileSize = document.createElement('p');
                fileSize.className = 'text-xs text-gray-500';
                fileSize.textContent = formatFileSize(file.size);
                
                fileName.appendChild(fileNameText);
                fileName.appendChild(fileSize);
                fileInfo.appendChild(fileIcon);
                fileInfo.appendChild(fileName);
                
                const removeBtn = document.createElement('button');
                removeBtn.className = 'text-gray-400 hover:text-red-500 transition-colors';
                removeBtn.innerHTML = '<i class="fa fa-times"></i>';
                removeBtn.addEventListener('click', () => {
                    selectedFiles.splice(index, 1);
                    updateFileList();
                    
                    if (selectedFiles.length === 0) {
                        fileListSection.classList.add('hidden');
                        mergeOptions.classList.add('hidden');
                    }
                });
                
                fileItem.appendChild(fileInfo);
                fileItem.appendChild(removeBtn);
                selectedFilesContainer.appendChild(fileItem);
            });
        }
        
        // 格式化文件大小
        function formatFileSize(bytes) {
            if (bytes === 0) return '0 Bytes';
            const k = 1024;
            const sizes = ['Bytes', 'KB', 'MB', 'GB'];
            const i = Math.floor(Math.log(bytes) / Math.log(k));
            return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
        }
        
        // 高级选项切换
        toggleAdvanced.addEventListener('click', () => {
            if (advancedOptions.classList.contains('hidden')) {
                advancedOptions.classList.remove('hidden');
                toggleAdvanced.innerHTML = '<i class="fa fa-chevron-up mr-1"></i> 隐藏';
            } else {
                advancedOptions.classList.add('hidden');
                toggleAdvanced.innerHTML = '<i class="fa fa-chevron-down mr-1"></i> 显示';
            }
        });
        
        // 处理文件合并
        mergeFilesBtn.addEventListener('click', async function() {
            // 隐藏之前的错误提示
            hideError();
            
            if (selectedFiles.length === 0) {
                showError('没有选择文件', '请先选择要合并的KML或KMZ文件。');
                mergeFilesBtn.classList.add('error-shake');
                setTimeout(() => mergeFilesBtn.classList.remove('error-shake'), 500);
                return;
            }
            
            // 验证输出文件名
            const fileName = outputFilename.value.trim();
            if (!fileName) {
                showError('无效的文件名', '请输入有效的输出文件名。');
                outputFilename.classList.add('border-error');
                setTimeout(() => outputFilename.classList.remove('border-error'), 2000);
                return;
            }
            
            // 显示处理进度
            mergeOptions.classList.add('hidden');
            processingSection.classList.remove('hidden');
            progressBar.style.width = '0%';
            progressText.textContent = '开始处理...';
            
            try {
                // 获取用户选择的选项
                const outputFormat = document.querySelector('input[name="output-format"]:checked').value;
                const keepStyles = document.getElementById('keep-styles').checked;
                const createFolders = document.getElementById('create-folders').checked;
                
                // 实际文件合并逻辑
                const mergedFile = await mergeKMLFiles(selectedFiles, outputFormat, { keepStyles, createFolders });
                
                // 更新结果区域
                resultFilename.textContent = `${fileName}.${outputFormat}`;
                downloadLink.href = mergedFile.url;
                downloadLink.download = `${fileName}.${outputFormat}`;
                
                // 显示结果
                processingSection.classList.add('hidden');
                resultSection.classList.remove('hidden');
                
                // 滚动到结果区域
                setTimeout(() => {
                    resultSection.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
                }, 300);
                
            } catch (error) {
                console.error('合并文件时出错:', error);
                progressText.textContent = '处理失败';
                
                // 显示错误详情
                showError(
                    '处理失败',
                    `合并文件时发生错误: ${error.message}<br>请检查您的文件是否有效。`
                );
                
                // 3秒后恢复
                setTimeout(() => {
                    processingSection.classList.add('hidden');
                    mergeOptions.classList.remove('hidden');
                }, 3000);
            }
        });
        
        // 模拟进度条
        async function simulateProgress(currentStep, totalSteps) {
            const progress = Math.round((currentStep / totalSteps) * 100);
            progressBar.style.width = `${progress}%`;
            
            if (progress < 30) {
                progressText.textContent = '正在解析文件...';
            } else if (progress < 60) {
                progressText.textContent = '正在合并内容...';
            } else if (progress < 90) {
                progressText.textContent = '正在生成输出文件...';
            } else {
                progressText.textContent = '即将完成...';
            }
            
            // 添加一点延迟，使进度条动画更流畅
            await new Promise(resolve => setTimeout(resolve, 300));
        }
        
        // 处理其他文件按钮
        processAnother.addEventListener('click', () => {
            clearAllFiles();
            resultSection.classList.add('hidden');
            dropArea.scrollIntoView({ behavior: 'smooth' });
        });
        
        // 清空所有文件
        clearFilesBtn.addEventListener('click', clearAllFiles);
        
        function clearAllFiles() {
            selectedFiles = [];
            updateFileList();
            fileListSection.classList.add('hidden');
            mergeOptions.classList.add('hidden');
            
            // 添加动画效果
            selectedFilesContainer.classList.add('opacity-0');
            setTimeout(() => {
                selectedFilesContainer.classList.remove('opacity-0');
            }, 300);
        }
        
        // 显示错误提示
        function showError(title, message) {
            errorTitle.textContent = title;
            errorMessage.innerHTML = `<p>${message}</p>`;
            uploadError.classList.remove('hidden');
            uploadError.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
        }
        
        // 隐藏错误提示
        function hideError() {
            uploadError.classList.add('hidden');
        }
        
        // 解析KML文件内容
        function parseKML(kmlContent) {
            const parser = new DOMParser();
            const xmlDoc = parser.parseFromString(kmlContent, "application/xml");
            
            // 检查解析是否成功
            const parseError = xmlDoc.querySelector("parsererror");
            if (parseError) {
                throw new Error("解析KML文件失败: " + parseError.textContent);
            }
            
            return xmlDoc;
        }
        
        // 提取KML文件中的内容
        function extractKMLContent(xmlDoc, options, fileName) {
            // 首先查找Document元素
            let contentElement = xmlDoc.querySelector("Document");
            
            // 如果没有Document元素，查找Folder元素
            if (!contentElement) {
                contentElement = xmlDoc.querySelector("Folder");
            }
            
            // 如果仍然没有找到，查找第一个Placemark
            if (!contentElement) {
                contentElement = xmlDoc.querySelector("Placemark");
            }
            
            // 如果还是没有找到任何内容元素
            if (!contentElement) {
                console.warn(`文件 ${fileName} 中未找到有效的KML内容元素`);
                return null;
            }
            
            // 如果用户选择创建文件夹结构，并且当前不是文件夹
            if (options.createFolders && contentElement.tagName !== "Folder") {
                const folder = xmlDoc.createElement("Folder");
                const name = xmlDoc.createElement("name");
                name.textContent = fileName;
                folder.appendChild(name);
                
                // 将原内容移动到文件夹中
                while (contentElement.firstChild) {
                    folder.appendChild(contentElement.firstChild);
                }
                
                // 添加原内容元素作为文件夹的子元素
                folder.appendChild(contentElement);
                
                return folder;
            }
            
            return contentElement;
        }
        
        // 复制样式定义（如果用户选择保留样式）
        function copyStyles(sourceDoc, targetDoc) {
            // 查找所有Style和StyleMap元素
            const styleElements = sourceDoc.querySelectorAll("Style, StyleMap");
            
            styleElements.forEach(style => {
                // 检查是否已有相同ID的样式
                const styleId = style.getAttribute("id");
                if (styleId && !targetDoc.querySelector(`Style[id="${styleId}"], StyleMap[id="${styleId}"]`)) {
                    const clonedStyle = targetDoc.importNode(style, true);
                    targetDoc.documentElement.querySelector("Document").appendChild(clonedStyle);
                }
            });
        }
        
        // 合并多个KML文件
        async function mergeKMLFiles(files, outputFormat, options) {
            const totalSteps = files.length * 2 + 1; // 每个文件解析和处理各一步，最后生成文件一步
            let currentStep = 0;
            
            // 创建一个新的KML文档
            const parser = new DOMParser();
            const serializer = new XMLSerializer();
            
            // 创建基本KML结构
            const newKMLContent = `<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
  <Document>
    <name>Merged KML</name>
    <description>由 KML 合并工具生成</description>
  </Document>
</kml>`;
            
            const newKMLDoc = parser.parseFromString(newKMLContent, "application/xml");
            const newDocument = newKMLDoc.querySelector("Document");
            
            // 处理每个文件
            for (const file of files) {
                await simulateProgress(currentStep++, totalSteps);
                
                try {
                    if (file.name.toLowerCase().endsWith('.kmz')) {
                        // 处理KMZ文件
                        await processKMZFile(file, newKMLDoc, newDocument, options);
                    } else {
                        // 处理KML文件
                        await processKMLFile(file, newKMLDoc, newDocument, options);
                    }
                    
                    await simulateProgress(currentStep++, totalSteps);
                } catch (error) {
                    console.error(`处理文件 ${file.name} 时出错:`, error);
                    // 继续处理其他文件，而不是中断整个过程
                    showNotification(`处理文件 ${file.name} 时出错: ${error.message}`, 'error');
                }
            }
            
            // 生成最终的KML内容
            await simulateProgress(currentStep, totalSteps);
            const mergedKML = serializer.serializeToString(newKMLDoc);
            
            // 根据输出格式处理
            if (outputFormat === 'kml') {
                // 创建 KML 文件的 Blob
                const blob = new Blob([mergedKML], { type: 'application/vnd.google-earth.kml+xml' });
                const url = URL.createObjectURL(blob);
                
                return {
                    url,
                    type: 'kml'
                };
            } else {
                // 对于 KMZ 格式，使用 JSZip 创建 ZIP 归档
                const zip = new JSZip();
                // 添加主 KML 文件
                zip.file("doc.kml", mergedKML);
                
                // 生成 ZIP 文件并创建下载链接
                const content = await zip.generateAsync({ type: "blob" });
                const url = URL.createObjectURL(content);
                
                return {
                    url,
                    type: 'kmz'
                };
            }
        }
        
        // 处理KML文件
        async function processKMLFile(file, newKMLDoc, newDocument, options) {
            return new Promise((resolve, reject) => {
                const reader = new FileReader();
                
                reader.onload = function(e) {
                    try {
                        const kmlContent = e.target.result;
                        const xmlDoc = parseKML(kmlContent);
                        
                        // 如果需要保留样式，复制样式定义
                        if (options.keepStyles) {
                            copyStyles(xmlDoc, newKMLDoc);
                        }
                        
                        // 提取内容
                        const contentElement = extractKMLContent(xmlDoc, options, file.name);
                        
                        if (contentElement) {
                            // 克隆内容并添加到新文档
                            const clonedContent = newKMLDoc.importNode(contentElement, true);
                            newDocument.appendChild(clonedContent);
                        } else {
                            throw new Error("未找到有效的KML内容");
                        }
                        
                        resolve();
                    } catch (error) {
                        reject(error);
                    }
                };
                
                reader.onerror = function() {
                    reject(new Error(`读取文件 ${file.name} 失败`));
                };
                
                reader.readAsText(file);
            });
        }
        
        // 处理KMZ文件
        async function processKMZFile(file, newKMLDoc, newDocument, options) {
            return new Promise((resolve, reject) => {
                const reader = new FileReader();
                
                reader.onload = async function(e) {
                    try {
                        const arrayBuffer = e.target.result;
                        const zip = new JSZip();
                        
                        // 加载KMZ文件（ZIP格式）
                        await zip.loadAsync(arrayBuffer);
                        
                        // 查找主KML文件（通常是doc.kml）
                        let kmlFile = null;
                        zip.forEach((relativePath, zipEntry) => {
                            if (relativePath.toLowerCase().endsWith('.kml')) {
                                kmlFile = zipEntry;
                                return false; // 停止遍历
                            }
                        });
                        
                        if (!kmlFile) {
                            throw new Error(`KMZ文件 ${file.name} 中未找到KML文件`);
                        }
                        
                        // 读取KML文件内容
                        const kmlContent = await kmlFile.async("string");
                        const xmlDoc = parseKML(kmlContent);
                        
                        // 如果需要保留样式，复制样式定义
                        if (options.keepStyles) {
                            copyStyles(xmlDoc, newKMLDoc);
                        }
                        
                        // 提取内容
                        const contentElement = extractKMLContent(xmlDoc, options, file.name);
                        
                        if (contentElement) {
                            // 克隆内容并添加到新文档
                            const clonedContent = newKMLDoc.importNode(contentElement, true);
                            newDocument.appendChild(clonedContent);
                        } else {
                            throw new Error("未找到有效的KML内容");
                        }
                        
                        resolve();
                    } catch (error) {
                        reject(error);
                    }
                };
                
                reader.onerror = function() {
                    reject(new Error(`读取文件 ${file.name} 失败`));
                };
                
                reader.readAsArrayBuffer(file);
            });
        }
        
        // 深色模式切换
        document.getElementById('theme-toggle').addEventListener('click', function() {
            const icon = this.querySelector('i');
            if (icon.classList.contains('fa-moon-o')) {
                icon.classList.remove('fa-moon-o');
                icon.classList.add('fa-sun-o');
                document.body.classList.add('dark-mode');
            } else {
                icon.classList.remove('fa-sun-o');
                icon.classList.add('fa-moon-o');
                document.body.classList.remove('dark-mode');
            }
        });
    </script>
</body>
</html>    